package cn.xc.basic.service.impl;

import cn.xc.basic.dto.SmsCodeDto;
import cn.xc.basic.exception.BusinessException;
import cn.xc.basic.service.IVerifyCodeSerivce;
import cn.xc.basic.util.SmsUtils;
import cn.xc.basic.util.StrUtils;
import cn.xc.basic.util.VerifyCodeUtils;
import cn.xc.user.domain.User;
import cn.xc.user.mapper.UserMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeSerivceImpl implements IVerifyCodeSerivce {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Override
    public String imgKey(String key) {
        String code = VerifyCodeUtils.generateVerifyCode(4);

        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        return VerifyCodeUtils.verifyCode(115,40,code);
    }

    @Override
    public void smsCode(SmsCodeDto smsCodeDto) {

        //一：校验
        //1.空值校验
        String imageCode = smsCodeDto.getImageCode();
        String phone = smsCodeDto.getPhone();
        String imageCodeKey = smsCodeDto.getImageCodeKey();
        if (StringUtils.isEmpty(phone)){
            throw new RuntimeException("手机不能空哦");
        }
        if (StringUtils.isEmpty(imageCode)){
            throw new RuntimeException("图形验证码不能空哦");
        }
        //2.图形验证码是否过期 和 是否过期
        Object key = redisTemplate.opsForValue().get(imageCodeKey);
        if (key==null) {
            throw new RuntimeException("图形验证码过期请重新获取");
        }
        if (!key.equals(imageCodeKey)){
            throw new RuntimeException("图形验证码错误！");
        }

        //3.手机号码是否注册过
        User user = userMapper.loadByPhone(phone);
        if (user==null){
            throw new RuntimeException("该手机号已被使用！");
        }

        //二：获取手机验证码，判断是否过期
        Object codeObj = redisTemplate.opsForValue().get("register:" + phone);
        //1.过期了或者没有验证码  -  使用工具类重新生成
        String smsCodeObj = null;
        if (codeObj==null){
            smsCodeObj = StrUtils.getRandomString(4);
        }else {
            //2.没有过期
            Long oldTime =  Long.parseLong(codeObj.toString().split(":")[1]);
            //2.1.判断是否过了重发时间  利用时间戳相减，大于或者等于
            //2.2.如果没有过重发时间 - 违规操作，直接抛异常
            if ((System.currentTimeMillis()-oldTime)<60*1000){
                throw new BusinessException("请勿频繁操作！");
            }
            //2.3.如果过了重发时间 - 使用以前的验证码
            smsCodeObj = codeObj.toString().split(":")[0];
        }

        //3.保存Redis - 重新设置3分钟
        redisTemplate.opsForValue().set("register:"+phone,smsCodeObj+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);


        //4.调用工具类发送短信 - sout打印
//        SmsUtils.sendSms(phone,"你的验证码为："+smsCodeObj+",请在3分钟内尽快使用");
        System.out.println(SmsUtils.sendSms(phone, "你的验证码为：" + smsCodeObj + ",请在3分钟内尽快使用"));

    }
}
